package com.mingrisoft;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.TextView;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.concurrent.ScheduledExecutorService;


/**
 * Created by susu on 2024/4/19.
 */
public class mqttManager {
    private static mqttManager instance;
    private String serverUri = "tcp://adtxnqb.iot.gz.baidubce.com:1883";  //这里可以填上各种云平台的物联网云平的域名+1883端口号，什么阿里云腾讯云百度云天工物接入都可以，
    // 这里我填的是我在我的阿里云服务器上搭建的EMQ平台的地址，
    // 注意：前缀“tcp：//”不可少，之前我没写，怎么都连不上，折腾了好久
    private String userName = "thingidp@adtxnqb|application|0|MD5";                    //然后是你的用户名，阿里云腾讯云百度云天工物接入这些平台你新建设备后就自动生成了
    private String passWord = "566e1fbe472d1c5fd88f0e32a0f05657";                    //用户名对应的密码，同样各种云平台都会对应生成密码，这里我的EMQ平台没做限制，所以用户名和密码可以随便填写
    private String clientId = "application"; //clientId很重要，不能重复，否则就会连不上，所以我定义成 app+当前时间
    private MqttClient mqtt_client;                         //创建一个mqtt_client对象
    MqttConnectOptions options;
    private ScheduledExecutorService scheduler;
    private String msgFromDev;
    private float temp_value, shum_value, co2_value, light_value;
    private TextView[] tvs;
    int arrSize;

    private mqttManager(TextView[] tvs, int arrSize) {
        mqtt_init_Connect();
        this.tvs = tvs;
        this.arrSize = arrSize;
    }

    private void mqtt_init_Connect() {
        try {
            //实例化mqtt_client，填入我们定义的serverUri和clientId，然后MemoryPersistence设置clientid的保存形式，默认为以内存保存
            mqtt_client = new MqttClient(serverUri, clientId, new MemoryPersistence());
            //创建并实例化一个MQTT的连接参数对象
            options = new MqttConnectOptions();
            //然后设置对应的参数
            options.setUserName(userName);                  //设置连接的用户名
            options.setPassword(passWord.toCharArray());    //设置连接的密码
            options.setConnectionTimeout(30);               // 设置超时时间，单位为秒
            options.setKeepAliveInterval(50);               //设置心跳,30s
            options.setAutomaticReconnect(true);            //是否重连
            //设置是否清空session,设置为false表示服务器会保留客户端的连接记录，设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(true);
            //连接mqtt服务器
            mqtt_client.connect(options);

        } catch (Exception e) {
            e.printStackTrace();
            Log.d("err", e.toString());
        }
    }

    public static synchronized mqttManager getInstance(TextView[] tvs, int arrSize) {
        if (instance == null) {
            instance = new mqttManager(tvs, arrSize);
            Log.d("debug", "instace is new");
        } else {
            Log.d("debug", "instance is raw");
        }
        return instance;
    }

    public void mqqtBack() {
        //设置回调
        mqtt_client.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                //连接丢失后，一般在这里面进行重连)
                try {
                    if (!mqtt_client.isConnected()) {
                        mqtt_client.reconnect();
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                    Log.d("err", e.toString());
                }
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                //publish后会执行到这里
                Log.d("debug:", "pulish complete");
            }

            @Override
            public void messageArrived(String topicName, MqttMessage message) throws Exception {
                //subscribe后得到的消息会执行到这里面
                msgFromDev = message.toString();
                Log.d("rev:", msgFromDev);
                updateUi(msgFromDev);
            }
        });
    }

    public void subscribeMessage(String topic, int Qos) {
        try {
            if (mqtt_client.isConnected()) {
                mqtt_client.subscribe(topic, Qos);
            }
        } catch (MqttException e) {
            e.printStackTrace();
            Log.e("err", "err" + e.toString());
        }
    }


    public void publishMessage(String topic, String message_str) {
        try {
            MqttMessage message = new MqttMessage();
            message.setPayload(message_str.getBytes());
            if (mqtt_client.isConnected()) {
                mqtt_client.publish(topic, message);
            }

        } catch (MqttException e) {
            e.printStackTrace();
            Log.d("err", e.toString());
        }
    }

    public void disconnect() {
        try {
            mqtt_client.disconnect();
        } catch (MqttException e) {
            e.printStackTrace();
            Log.d("err", e.toString());
        }

    }

    public void flashAbtrr(TextView[] tvs, int arrSize) {
        this.tvs = tvs;
        this.arrSize = arrSize;
    }

    // 其他MQTT操作方法，例如发布消息、订阅主题等
    private void updateUi(final String msg) {
        Handler handler = new Handler(Looper.getMainLooper());

        handler.post(new Runnable() {

            @Override
            public void run() {
                String temp = "\"Atemp\":";
                String Ahum = "\"Ahum\":";
                String Shum = "\"Shum\":";
                String light = "\"light\":";
                String co2 = "\"co2\":";
                String type = "\"type\":";
                int nStart = msg.indexOf(type);
                int subStrLen = type.length();
                if (nStart > 0) {
                    if ((msg.substring(nStart + subStrLen, nStart + subStrLen + 1).equals("0"))) {

                        nStart = msg.indexOf(temp);
                        subStrLen = temp.length();
                        String tempVal = msg.substring(nStart + subStrLen, nStart + subStrLen + 5);
                        Log.i("debug",tempVal);
                        nStart = msg.indexOf(Ahum);
                        subStrLen = Ahum.length();
                        String ahumVal = msg.substring(nStart + subStrLen, nStart + subStrLen + 5);
                        Log.i("debug",ahumVal);
                        nStart = msg.indexOf(Shum);
                        subStrLen = Shum.length();
                        String shumVal = msg.substring(nStart + subStrLen, nStart + subStrLen + 5);
                        Log.i("debug",shumVal);
                        nStart = msg.indexOf(light);
                        subStrLen = light.length();
                        String lightval = msg.substring(nStart + subStrLen, nStart + subStrLen + 5);
                        Log.i("debug",lightval);
                        nStart = msg.indexOf(co2);
                        subStrLen = co2.length();
                        String co2Val = msg.substring(nStart + subStrLen, nStart + subStrLen + 4);
                        Log.i("debug",co2Val);
                        if (tvs.length > 0) {
                            tvs[0].setText(tempVal + "℃");
                            tvs[1].setText(ahumVal + "%");
                            tvs[2].setText(shumVal + "%");
                            tvs[3].setText(co2Val);
                            tvs[4].setText(lightval);
                            tvs[5].append(msg + "\n");
                        } else {
                            temp_value = Float.valueOf(tempVal);
                            shum_value = Float.valueOf(shumVal);
                            light_value = Float.valueOf(lightval);
                            co2_value = Float.valueOf(co2Val);
                        }
                    }
                    else if ((msg.substring(nStart + subStrLen, nStart + subStrLen + 1).equals("1")))
                    {
                        if (tvs.length > 0)
                        {
                            tvs[5].append(msg + "\n");
                        }
                    }
                }

            }

        });
    }

    public float getTempValue() {
        return temp_value;
    }

    public float getShumValue() {
        return shum_value;
    }

    public float getLightValue() {
        return light_value;
    }

    public float getCo2Value() {
        return co2_value;
    }
}